package com.ruoyi.syrw.aspectj;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.syrw.annotation.FIllBasicInfo;
import com.ruoyi.report_tg.domain.vo.ExcelGeneralVo;
import com.ruoyi.sycs.domain.bo.UseFanganQueryBo;
import com.ruoyi.sycs.service.IBsFanganInfoService;
import com.ruoyi.syrw.component.ReportMapperEnum;
import com.ruoyi.syrw.domain.BiExcelType;
import com.ruoyi.syrw.domain.BsDataReport;
import com.ruoyi.syrw.domain.RefReportExcel;
import com.ruoyi.syrw.domain.vo.BsDataReportVo;
import com.ruoyi.syrw.domain.vo.RefReportExcelVo;
import com.ruoyi.syrw.mapper.BiExcelTypeMapper;
import com.ruoyi.syrw.mapper.BsDataReportMapper;
import com.ruoyi.syrw.mapper.RefReportExcelMapper;
import com.ruoyi.syrw.service.IBsDataReportService;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.ycl.domain.BsJctz;
import com.ruoyi.ycl.domain.vo.BsJctzVo;
import com.ruoyi.ycl.mapper.BsJctzMapper;
import com.ruoyi.ycl.service.IBsJctzService;
import com.ruoyi.yp.domain.BsYp;
import com.ruoyi.yp.domain.vo.BsYpVo;
import com.ruoyi.yp.mapper.BsYpMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 填充 基础的信息
 *
 * @author zyb
 */
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
@Order(100)
public class FillBasicInfoAspect {

    private final RefReportExcelMapper refReportExcelMapper;
    private final BsDataReportMapper reportMapper;
    private final IBsDataReportService reportService;
    private final BsYpMapper ypMapper;
    private final ISysDictDataService dictDataService;
    private final ISysDeptService deptService;
    private final BsJctzMapper jctzMapper;
    private final IBsJctzService jctzService;
    private final BiExcelTypeMapper excelTypeMapper;
    private final IBsFanganInfoService fanganInfoService;

    /**
     * 填充字段
     * 处理完请求后执行
     *
     * @param joinPoint 切点
     */
    @Around(value = "@annotation(fillBasicInfo)")
    public Object fillResult(ProceedingJoinPoint joinPoint, FIllBasicInfo fillBasicInfo) throws Throwable {
        // 2024年7月19日 10:16:10 add excelId为空时的处理
        Long excelId = (Long) joinPoint.getArgs()[0];
        ExcelGeneralVo result = (ExcelGeneralVo) joinPoint.proceed();
        // 空表打印
        if (1111L == excelId) {
            // 主要仪器设备名称及编号 (找一个 这个类型的 这个试验室的 表单中的 主要仪器赋值在这里)
            ReportMapperEnum mapperEnum = ReportMapperEnum.findByServiceClass(joinPoint.getTarget().getClass());
            String excelTypeLabel = mapperEnum.getLabel();
            // 2024年9月23日 暂时修复 1but2 错误
            Long excelTypeId = excelTypeMapper.selectVoList(new LambdaQueryWrapper<BiExcelType>()
                .eq(BiExcelType::getLabel, excelTypeLabel)).get(0).getExcelTypeId();
            List<Long> reportIdList = reportMapper.selectList(new LambdaQueryWrapper<BsDataReport>()
                .eq(BsDataReport::getDeptId, LoginHelper.getDeptId())
                .orderByDesc(BsDataReport::getReportDate))
                .stream().map(BsDataReport::getReportId).collect(Collectors.toList());
            if (CollUtil.isEmpty(reportIdList)) {
                return result;
            }
            List<Long> typeExcelIdList = refReportExcelMapper.selectList(new LambdaQueryWrapper<RefReportExcel>()
                .in(RefReportExcel::getReportId, reportIdList)
                .eq(RefReportExcel::getExcelTypeId, excelTypeId)
                .last("limit 10"))
                .stream().map(RefReportExcel::getExcelId).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(typeExcelIdList)) {
                for (Long aLong : typeExcelIdList) {
                    Object serviceImpl = SpringUtil.getBean(mapperEnum.getServiceClazz());
                    try {
                        Method queryById = mapperEnum.getServiceClazz().getDeclaredMethod("queryById", Long.class);
                        ExcelGeneralVo tempRes = (ExcelGeneralVo) queryById.invoke(serviceImpl, aLong);
                        if (StrUtil.isNotEmpty(tempRes.getShebIds())) {
                            result.setShebIds(tempRes.getShebIds());
                            result.setZhuyyqsbmcjbh(tempRes.getZhuyyqsbmcjbh());
                            return result;
                        }
                    } catch (NoSuchMethodException e) {
                        throw new ServiceException("在" + mapperEnum.getLabel() + "对应的Service中未找到queryById方法");
                    } catch (InvocationTargetException e) {
                        if (e.getTargetException() instanceof ServiceException) {
                            throw (ServiceException) e.getTargetException();
                        }
                        throw new ServiceException("在" + mapperEnum.getLabel() + "对应的Service调用queryById方法失败，具体原因：" + e.getMessage());
                    }

                }
            }
            return result;
        }
        RefReportExcelVo refReportExcelVo = refReportExcelMapper.selectVoOne(new LambdaQueryWrapper<RefReportExcel>()
            .eq(RefReportExcel::getExcelId, excelId));
        Long excelTypeId = refReportExcelVo.getExcelTypeId();
        Long reportId = refReportExcelVo.getReportId();
        BsDataReportVo reportVo = reportService.queryById(reportId);
        Long deptId = reportVo.getDeptId();
        Long checkDeptId = reportVo.getCheckDeptId();

        // 试验室信息
        SysDept sysDept = deptService.selectDeptById(deptId);
        result.setJiancdwmc(sysDept.getTestingCompany());
        result.setGongcmc(sysDept.getConstructionProject());
        // 试验任务增加 抽检标段下拉框，内部表格中，施工委托单位从 抽检标段中 读取
        if (ObjUtil.isNotNull(checkDeptId)) {
            result.setShigwtdw(deptService.selectDeptById(checkDeptId).getConstructionCompany());
        }else {
            result.setShigwtdw(sysDept.getConstructionCompany());
        }


        // 2024年8月26日 ADD 附加声明 begin
        // 如果此时为空 或者 是“附加声明：” 需要附加声明。
        if (StrUtil.isEmpty(result.getFujsm()) || !"附加声明：".equals(result.getFujsm())) {
            // 如果是最底层 试验室 则填充附加声明
            if (deptService.isLastDept(deptId)) {
                result.setFujsm("附加声明：1、监理单位：" + StrUtil.emptyToDefault(sysDept.getSupervisionCompany(), "")
                    + "\n \t  2、见证人：");
            }
        }
        // 2024年8月26日 ADD 附加声明 end
        // 样品信息
        BsYpVo bsYpVo = ypMapper.selectVoOne(new LambdaQueryWrapper<BsYp>().eq(BsYp::getYpNum, reportVo.getYpCode()));
        result.setYangpmc(bsYpVo.getYangpmc());
        result.setYangpsl(bsYpVo.getYangpsl());
        result.setYangpzt(bsYpVo.getYangpzt());
        result.setYangpsj(ObjUtil.isNotNull(bsYpVo.getYpDate()) ? DateUtil.format(bsYpVo.getYpDate(), Constants.EXCEL_DATE_FORMAL) : null);
        result.setGongcbwyt(bsYpVo.getGcbw());
        // 代表数量
        result.setDaibsl(bsYpVo.getDaibsl());
        // 样品编号
        result.setYangpbh(reportVo.getYpCode());

        // 试验检测日期 改为可编辑 2024年11月15日
        if (ObjUtil.isNotNull(reportVo.getTzId())) {
//            BsJctzVo bsJctzVo = jctzMapper.selectVoOne(new LambdaQueryWrapper<BsJctz>().eq(BsJctz::getTzId, reportVo.getTzId()));
            BsJctzVo bsJctzVo = jctzService.queryById(reportVo.getTzId());
            // 取样地点 / 取样位置
            result.setQuydd(bsJctzVo.getCunfwz());
            // 产地 / 生产厂家
            result.setCd(bsJctzVo.getChandcj());
            // 规格型号 / 样品规格
            result.setGuigxh(bsJctzVo.getGuigxh());
            // 批号
            result.setPih(bsJctzVo.getPih());
            // 进场日期
            result.setJincrq(ObjUtil.isNotNull(bsJctzVo.getInDate()) ? DateUtil.format(bsJctzVo.getInDate(), Constants.EXCEL_DATE_FORMAL) : null);
            // 出厂日期
            result.setChucrq(ObjUtil.isNotNull(bsJctzVo.getChucDate()) ? DateUtil.format(bsJctzVo.getChucDate(), Constants.EXCEL_DATE_FORMAL) : null);
            // 代表数量  以 试验任务层填的为准，否则取进场台账的代表数量
            if (StrUtil.isEmpty(result.getDaibsl())) {
                result.setDaibsl(bsJctzVo.getDaibsl());
            }
        }
        // mod 2024-8-26 试验检测日期增加第二个字段 begin
        if(StrUtil.isEmpty(result.getShiyjcrq())){
            if (ObjUtil.isNull(reportVo.getReportDateEnd())) {
                result.setShiyjcrq(ObjUtil.isNotNull(reportVo.getReportDate()) ? DateUtil.format(reportVo.getReportDate(), Constants.EXCEL_DATE_FORMAL) : null);
            }else {
                result.setShiyjcrq(DateUtil.format(reportVo.getReportDate(), Constants.EXCEL_DATE_FORMAL) + "～"
                    + DateUtil.format(reportVo.getReportDateEnd(), Constants.EXCEL_DATE_FORMAL));
            }
        }
        // mod 2024-8-26 试验检测日期增加第二个字段 end

        // 考虑到 以下信息 既要引用,又要可编辑,只能单向关联. -- 202040816 改为不能编辑 强制填充引用
        // 记录编号
//        if (StrUtil.isEmpty(result.getJilbh())) {
            result.setJilbh(reportVo.getJlCode());
//        }
        // 报告编号
//        if (StrUtil.isEmpty(result.getBaogbh())) {
            result.setBaogbh(reportVo.getBgCode());
//        }

        // 3 页码处理
        // 3.1 如果是报告 则 统计报告的总页数 和 自己的所属页码
        List<RefReportExcelVo> refReportExcelVos = refReportExcelMapper.selectVoList(new LambdaQueryWrapper<RefReportExcel>()
            .eq(RefReportExcel::getReportId, reportId));
        refReportExcelVos.forEach(v ->{
            v.setVo(excelTypeMapper.selectById(v.getExcelTypeId()));
        });
        // 2024年6月20日 15:08:20 add 排序
        List<RefReportExcelVo> reportExcelVos = refReportExcelVos.stream().sorted().collect(Collectors.toList());
        if ("1".equals(result.getBgFlag())) {
            List<Long> bgExcelIds = reportExcelVos.stream().filter(v -> {
                ReportMapperEnum mapperEnum = ReportMapperEnum.findByLabel(v.getLabel());
                Assert.notNull(mapperEnum, v.getLabel() + "后台注册信息有误");
                return mapperEnum.getBgFlag();
            }).map(RefReportExcelVo::getExcelId).collect(Collectors.toList());

            result.setPage((long) bgExcelIds.indexOf(result.getExcelId()) + 1);
            result.setTotalPage((long) bgExcelIds.size());
        } else {
            List<Long> jlExcelIds = reportExcelVos.stream().filter(v -> {
                ReportMapperEnum mapperEnum = ReportMapperEnum.findByLabel(v.getLabel());
                Assert.notNull(mapperEnum, v.getLabel() + "后台注册信息有误");
                return !mapperEnum.getBgFlag();
            }).map(RefReportExcelVo::getExcelId).collect(Collectors.toList());

            result.setPage((long) jlExcelIds.indexOf(result.getExcelId()) + 1);
            result.setTotalPage((long) jlExcelIds.size());
        }

        // 20241021 add 使用的小数点方案
        UseFanganQueryBo queryBo = new UseFanganQueryBo(excelId, deptId, excelTypeId);
        result.setFanganVo(fanganInfoService.getFactUseFangan(queryBo));

        return result;
    }

}
